'use strict';

const Service = require('egg').Service;

class LocationService extends Service {

  /**
   * 获取用户当前位置
   * @param {Object} options - 选项
   * @param {string} options.ip - 用户IP地址
   * @param {number} options.lat - 纬度（可选）
   * @param {number} options.lng - 经度（可选）
   * @param {string} options.address - 地址（可选）
   * @returns {Object} 位置信息
   */
  async getCurrentLocation(options = {}) {
    const { ip, lat, lng, address } = options;
    
    try {
      // 如果提供了经纬度，直接进行逆地理编码
      if (lat && lng) {
        return await this.reverseGeocode(lat, lng);
      }
      
      // 如果提供了地址，进行地理编码
      if (address) {
        return await this.geocode(address);
      }
      
      // 否则使用IP定位
      return await this.getLocationByIP(ip);
      
    } catch (error) {
      console.error('获取位置信息失败:', error);
      return this.getDefaultLocation();
    }
  }

  /**
   * 根据IP获取位置信息
   * @param {string} ip - IP地址
   * @returns {Object} 位置信息
   */
  async getLocationByIP(ip) {
    try {
      // 检查是否为本地IP地址
      if (this.isLocalIP(ip)) {
        console.log('🏠 检测到本地IP地址，使用默认位置');
        return this.getDefaultLocation();
      }

      const provider = this.config.location?.provider || 'ip';

      if (provider === 'amap' && this.config.location?.amapKey) {
        try {
          return await this.getLocationByAmapIP(ip);
        } catch (error) {
          console.log('高德IP定位失败，降级到免费IP定位:', error.message);
          // 降级到免费IP定位
          return await this.getLocationByFreeIP(ip);
        }
      }

      // 使用免费IP定位服务
      return await this.getLocationByFreeIP(ip);

    } catch (error) {
      console.error('IP定位失败:', error);
      return this.getDefaultLocation();
    }
  }

  /**
   * 使用高德地图IP定位
   * @param {string} ip - IP地址
   * @returns {Object} 位置信息
   */
  async getLocationByAmapIP(ip) {
    const key = this.config.location.amapKey;
    const url = `https://restapi.amap.com/v3/ip?ip=${ip}&key=${key}`;

    const response = await this.ctx.curl(url, {
      method: 'GET',
      dataType: 'json',
      timeout: 5000
    });

    if (response.status === 200 && response.data.status === '1') {
      const data = response.data;

      // 处理不同的响应格式
      let latitude = 0;
      let longitude = 0;

      if (data.rectangle && typeof data.rectangle === 'string') {
        // 标准格式：rectangle包含坐标范围
        const [lng, lat] = data.rectangle.split(';')[0].split(',');
        latitude = parseFloat(lat);
        longitude = parseFloat(lng);
      } else if (data.location && typeof data.location === 'string') {
        // 备用格式：location包含坐标
        const [lng, lat] = data.location.split(',');
        latitude = parseFloat(lat);
        longitude = parseFloat(lng);
      } else {
        // 使用城市中心坐标作为默认值
        const cityCoords = this.getCityCoordinates(data.city || data.province);
        latitude = cityCoords.lat;
        longitude = cityCoords.lng;
      }

      // 处理城市信息 - 支持数组和字符串格式
      let city = '';
      let province = '';

      // 处理city字段
      if (Array.isArray(data.city)) {
        city = data.city.length > 0 ? data.city[0] : '';
      } else if (typeof data.city === 'string') {
        city = data.city;
      }

      // 处理province字段
      if (Array.isArray(data.province)) {
        province = data.province.length > 0 ? data.province[0] : '';
      } else if (typeof data.province === 'string') {
        province = data.province;
      }

      // 如果城市和省份都为空，可能是本地IP或无法定位的IP
      if (!city && !province) {
        console.log('⚠️ 高德IP定位返回空数据，IP:', ip);
        console.log('原始响应:', JSON.stringify(data, null, 2));
        // 抛出错误，让系统降级到免费IP定位
        throw new Error('高德IP定位返回空数据');
      }

      // 移除常见后缀
      if (typeof city === 'string' && city) {
        city = city.replace(/市$|区$|县$/, '');
      }

      if (typeof province === 'string' && province) {
        province = province.replace(/省$|市$|自治区$|特别行政区$/, '');
      }

      // 如果城市为空但省份不为空，使用省份作为城市
      if (!city && province) {
        city = province;
      }

      const locationData = {
        city: city || '未知城市',
        province: province || '未知省份',
        country: '中国',
        latitude,
        longitude,
        address: `${province}${city}`,
        source: 'amap_ip',
        raw: data // 保留原始数据
      };

      console.log('✅ 高德IP定位解析结果:', locationData);
      return locationData;
    }

    throw new Error('高德IP定位失败');
  }

  /**
   * 使用免费IP定位服务
   * @param {string} ip - IP地址
   * @returns {Object} 位置信息
   */
  async getLocationByFreeIP(ip) {
    // 如果是本地IP，直接返回默认位置
    if (this.isLocalIP(ip)) {
      console.log('🏠 免费IP定位检测到本地IP，返回默认位置');
      return this.getDefaultLocation();
    }

    const url = `http://ip-api.com/json/${ip}?lang=zh-CN&fields=status,message,country,regionName,city,lat,lon,timezone`;

    console.log(`🔍 免费IP定位请求: ${url}`);

    const response = await this.ctx.curl(url, {
      method: 'GET',
      dataType: 'json',
      timeout: 5000
    });

    console.log('📍 免费IP定位响应:', JSON.stringify(response.data, null, 2));

    if (response.status === 200 && response.data.status === 'success') {
      const data = response.data;

      // 处理城市名称
      let city = data.city || '';
      let province = data.regionName || '';

      // 移除常见的后缀
      if (typeof city === 'string') {
        city = city.replace(/市$|区$|县$/, '');
      }

      if (typeof province === 'string') {
        province = province.replace(/省$|市$|自治区$|特别行政区$/, '');
      }

      // 如果城市为空，使用省份作为城市
      if (!city && province) {
        city = province;
      }

      const locationData = {
        city: city || '未知城市',
        province: province || '未知省份',
        country: data.country || '中国',
        latitude: data.lat || 0,
        longitude: data.lon || 0,
        address: `${province}${city}`,
        source: 'ip_api',
        timezone: data.timezone,
        raw: data // 保留原始数据
      };

      console.log('✅ IP定位解析结果:', locationData);
      return locationData;
    }

    console.error('❌ 免费IP定位失败:', response.data);
    throw new Error(`免费IP定位失败: ${response.data.message || '未知错误'}`);
  }

  /**
   * 地理编码（地址转坐标）
   * @param {string} address - 地址
   * @returns {Object} 位置信息
   */
  async geocode(address) {
    try {
      const provider = this.config.location?.provider || 'amap';
      
      switch (provider) {
        case 'amap':
          return await this.amapGeocode(address);
        case 'baidu':
          return await this.baiduGeocode(address);
        case 'tencent':
          return await this.tencentGeocode(address);
        default:
          return await this.amapGeocode(address);
      }
    } catch (error) {
      console.error('地理编码失败:', error);
      return this.getDefaultLocation();
    }
  }

  /**
   * 逆地理编码（坐标转地址）
   * @param {number} lat - 纬度
   * @param {number} lng - 经度
   * @returns {Object} 位置信息
   */
  async reverseGeocode(lat, lng) {
    try {
      const provider = this.config.location?.provider || 'amap';
      
      switch (provider) {
        case 'amap':
          return await this.amapReverseGeocode(lat, lng);
        case 'baidu':
          return await this.baiduReverseGeocode(lat, lng);
        case 'tencent':
          return await this.tencentReverseGeocode(lat, lng);
        default:
          return await this.amapReverseGeocode(lat, lng);
      }
    } catch (error) {
      console.error('逆地理编码失败:', error);
      return this.getDefaultLocation();
    }
  }

  /**
   * 高德地图地理编码
   * @param {string} address - 地址
   * @returns {Object} 位置信息
   */
  async amapGeocode(address) {
    const key = this.config.location?.amapKey;
    if (!key || key === 'your_amap_key') {
      throw new Error('高德地图API Key未配置');
    }
    
    const url = `https://restapi.amap.com/v3/geocode/geo?address=${encodeURIComponent(address)}&key=${key}`;
    
    const response = await this.ctx.curl(url, {
      method: 'GET',
      dataType: 'json',
      timeout: 5000
    });
    
    if (response.status === 200 && response.data.status === '1' && response.data.geocodes.length > 0) {
      const data = response.data.geocodes[0];
      const [lng, lat] = data.location.split(',');
      
      return {
        city: data.city,
        province: data.province,
        country: '中国',
        latitude: parseFloat(lat),
        longitude: parseFloat(lng),
        address: data.formatted_address,
        source: 'amap_geocode'
      };
    }
    
    throw new Error('高德地理编码失败');
  }

  /**
   * 高德地图逆地理编码
   * @param {number} lat - 纬度
   * @param {number} lng - 经度
   * @returns {Object} 位置信息
   */
  async amapReverseGeocode(lat, lng) {
    const key = this.config.location?.amapKey;
    if (!key || key === 'your_amap_key') {
      throw new Error('高德地图API Key未配置');
    }

    const url = `https://restapi.amap.com/v3/geocode/regeo?location=${lng},${lat}&key=${key}&radius=1000&extensions=all`;

    console.log(`🔍 高德逆地理编码请求: ${url}`);

    const response = await this.ctx.curl(url, {
      method: 'GET',
      dataType: 'json',
      timeout: 5000
    });

    console.log('📍 高德逆地理编码响应:', JSON.stringify(response.data, null, 2));

    if (response.status === 200 && response.data.status === '1') {
      const regeocode = response.data.regeocode;
      const addressComponent = regeocode.addressComponent;

      // 解析城市信息，处理不同的地址格式
      let city = addressComponent.city;
      let province = addressComponent.province;

      // 处理直辖市的情况（如北京、上海等）
      if (!city || city === '' || city == []) {
        city = province;
      }

      // 移除市、区等后缀，获取纯城市名
      if (typeof city === 'string') {
        city = city.replace(/市$|区$|县$/, '');
      }

      if (typeof province === 'string') {
        province = province.replace(/省$|市$|自治区$|特别行政区$/, '');
      }

      const locationData = {
        city: city || '未知城市',
        province: province || '未知省份',
        country: addressComponent.country || '中国',
        district: addressComponent.district || '',
        township: addressComponent.township || '',
        latitude: lat,
        longitude: lng,
        address: regeocode.formatted_address || `${province}${city}`,
        source: 'amap_reverse',
        raw: addressComponent // 保留原始数据用于调试
      };

      console.log('✅ 解析的位置信息:', locationData);
      return locationData;
    }

    console.error('❌ 高德逆地理编码失败:', response.data);
    throw new Error(`高德逆地理编码失败: ${response.data.info || '未知错误'}`);
  }

  /**
   * 检查是否为本地IP地址
   * @param {string} ip - IP地址
   * @returns {boolean} 是否为本地IP
   */
  isLocalIP(ip) {
    if (!ip) return true;

    const localIPs = [
      '127.0.0.1',
      'localhost',
      '::1',
      '0.0.0.0'
    ];

    // 检查是否为本地回环地址
    if (localIPs.includes(ip)) {
      return true;
    }

    // 检查是否为内网地址
    const privateRanges = [
      /^10\./,                    // 10.0.0.0/8
      /^172\.(1[6-9]|2[0-9]|3[0-1])\./, // 172.16.0.0/12
      /^192\.168\./,              // 192.168.0.0/16
      /^169\.254\./               // 169.254.0.0/16 (链路本地地址)
    ];

    return privateRanges.some(range => range.test(ip));
  }

  /**
   * 获取默认位置（北京）
   * @returns {Object} 默认位置信息
   */
  getDefaultLocation() {
    return {
      city: '北京',
      province: '北京市',
      country: '中国',
      latitude: 39.9042,
      longitude: 116.4074,
      address: '北京市',
      source: 'default'
    };
  }

  /**
   * 获取城市坐标
   * @param {string} cityName - 城市名称
   * @returns {Object} 城市坐标
   */
  getCityCoordinates(cityName) {
    const cityMap = {
      '北京': { lat: 39.9042, lng: 116.4074 },
      '北京市': { lat: 39.9042, lng: 116.4074 },
      '上海': { lat: 31.2304, lng: 121.4737 },
      '上海市': { lat: 31.2304, lng: 121.4737 },
      '广州': { lat: 23.1291, lng: 113.2644 },
      '广州市': { lat: 23.1291, lng: 113.2644 },
      '深圳': { lat: 22.5431, lng: 114.0579 },
      '深圳市': { lat: 22.5431, lng: 114.0579 },
      '杭州': { lat: 30.2741, lng: 120.1551 },
      '杭州市': { lat: 30.2741, lng: 120.1551 },
      '南京': { lat: 32.0603, lng: 118.7969 },
      '南京市': { lat: 32.0603, lng: 118.7969 },
      '武汉': { lat: 30.5928, lng: 114.3055 },
      '武汉市': { lat: 30.5928, lng: 114.3055 },
      '成都': { lat: 30.6598, lng: 104.0633 },
      '成都市': { lat: 30.6598, lng: 104.0633 },
      '西安': { lat: 34.3416, lng: 108.9398 },
      '西安市': { lat: 34.3416, lng: 108.9398 },
      '重庆': { lat: 29.5647, lng: 106.5507 },
      '重庆市': { lat: 29.5647, lng: 106.5507 },
      '天津': { lat: 39.3434, lng: 117.3616 },
      '天津市': { lat: 39.3434, lng: 117.3616 },
      '苏州': { lat: 31.2989, lng: 120.5853 },
      '苏州市': { lat: 31.2989, lng: 120.5853 },
      '青岛': { lat: 36.0986, lng: 120.3719 },
      '青岛市': { lat: 36.0986, lng: 120.3719 },
      '大连': { lat: 38.9140, lng: 121.6147 },
      '大连市': { lat: 38.9140, lng: 121.6147 },
      '宁波': { lat: 29.8683, lng: 121.5440 },
      '宁波市': { lat: 29.8683, lng: 121.5440 },
      '厦门': { lat: 24.4798, lng: 118.0819 },
      '厦门市': { lat: 24.4798, lng: 118.0819 }
    };

    return cityMap[cityName] || { lat: 39.9042, lng: 116.4074 }; // 默认北京
  }

  /**
   * 获取城市列表
   * @returns {Array} 城市列表
   */
  getCityList() {
    return [
      { name: '北京', code: '110000', lat: 39.9042, lng: 116.4074 },
      { name: '上海', code: '310000', lat: 31.2304, lng: 121.4737 },
      { name: '广州', code: '440100', lat: 23.1291, lng: 113.2644 },
      { name: '深圳', code: '440300', lat: 22.5431, lng: 114.0579 },
      { name: '杭州', code: '330100', lat: 30.2741, lng: 120.1551 },
      { name: '南京', code: '320100', lat: 32.0603, lng: 118.7969 },
      { name: '武汉', code: '420100', lat: 30.5928, lng: 114.3055 },
      { name: '成都', code: '510100', lat: 30.6598, lng: 104.0633 },
      { name: '西安', code: '610100', lat: 34.3416, lng: 108.9398 },
      { name: '重庆', code: '500000', lat: 29.5647, lng: 106.5507 }
    ];
  }
}

module.exports = LocationService;
